<!--
@Descripttion 表格
@version 1.0.0
@Author Bell
@ 使用
  引入组件
    import Table from '@/components/table/table'
  注册组件
    components: {
      Table
    }
  使用
    通过$refs中的selectData获取被选中的行数据 如:this.$refs.xxx.selectData
    <Table @select="(list) => {xxx = list}" :data="[{}]" :columns="[{title: 'ID', key: 'id', show: true, width: 100}]">插槽区域</Table>
    <Table @select="(list) => {xxx = list}" :handleWidth="0" pageType="no-search" :data="[{}]" rowKey="id" columnMark="tableKey" :columns="[{title: 'ID', key: 'id', show: true, width: 100}]">插槽区域</Table>
    @select            Function 非必填     表格行选中后调用的回调，参数:selection 不填无选择列功能
    handleWidth        Number   默认值(0)  操作栏最小宽度，值为0时即使栏插槽中包含了代码也不显示操作栏
    pageType           String   默认('')   页面类型 no-search:没有搜索栏 no-button:没有按钮 no-all:没有搜索栏和按钮
    data               Array    必填       列表数据
    rowKey             String   默认('id') 表格行标识
    columnMark(唯一值)  String   默认('')   表格列标识（值为''时表格不可手动配置） 用于TableSetting 组件中localStorage存储数据
    columns            Array    必填       表格列 数组中对象格式见(>数据格式说明1)
  其他说明
    插槽参数: row(当前行对象) index(当前行下标)
    >数据格式说明1：
      {
        title: '',     // String  必填   表格标题
        key: '',       // String  必填   字段取值key值(支持对象嵌套取值，如：user.name)
        show: true,    // Boolean 必填   是否显示
        width: 200,    // Number  非必填 表格列宽
        format: {      // Object  非必填 数据格式化
          method: functionName, // Function 必填   函数
          params: ''            // Any      非必填 参数
        },
        // 是否图片 Object 非必填
        isImage: {
          type: 'icon',                  // String   必填   图片类型 icon小图标 image原图
        },
        // 是否开关 Object 非必填
        isSwitch: {
          method: functionName,          // Function 必填   函数  传入3个参数(新的值, 当前行数据, 当前下标)
        },
        // 是否格式化日期 String 非必填
        isDate: 'YYYY-MM-DD HH:mm:ss', // 值为格式化规则 必填
        // 是否格式化金额 String 非必填
        isMoney: true,
      }
 -->
<template>
  <div class="table-content" :class="pageType">
    <TableSetting v-if="columnMark" @redraw="redraw" :params="tableSet" :columnMark="columnMark" :columns="columnList" :columnsDefault="columns" />
    <el-table
      border height="100%" ref="customerTable"
      :data="data"
      @row-click="rowClick"
      @row-dblclick="rowDblclick"
      @selection-change="selectionChange"
      :row-class-name="rowClassName"
    >
      <el-table-column width="40" type="selection" align="center" v-if="isSelect"></el-table-column>
      <el-table-column width="60" type="index" show-overflow-tooltip>
        <template slot="header" slot-scope="scope">
          <i v-if="columnMark" @click="tableSet.show = true" class="el-icon-s-tools cursor-p"></i>
          <span v-else>{{$t('table.Serial number')}}</span>
        </template>
      </el-table-column>
      <!-- 循环表格列 -->
      <template v-for="(clo, index) in columnList">
        <el-table-column
          v-if="clo.show"
          :key="index"
          :label="clo.title"
          :width="clo.width ? clo.width : ''"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <!-- 类型列 -->
            <template v-if="clo.isImage || clo.isSwitch || clo.isDate || clo.isMoney || clo.isTag">
              <!-- image -->
              <span v-if="clo.isImage" @click.stop="preview(scope.row[clo.key])">
                <el-image v-if="clo.isImage.type === 'image'" :src="scope.row[clo.key]" fit="contain" class="table-img"></el-image>
                <i v-if="clo.isImage.type === 'icon'" class="el-icon-picture c-primary"></i>
              </span>
              <!-- switch -->
              <el-switch v-if="clo.isSwitch" v-model="scope.row[clo.key]"
                @change="clo.isSwitch.method($event, scope.row, scope.$index)" @click.stop.native
                :active-value="1" :inactive-value="0" active-color="#13ce66"
              ></el-switch>
              <!-- date -->
              <span v-if="clo.isDate">{{dateFormat(scope.row[clo.key], scope.row, clo.isDate)}}</span>
              <!-- money -->
              <span v-if="clo.isMoney">{{moneyFormat(scope.row[clo.key], scope.row)}}</span>
              <!-- tag -->
              <el-tag v-if="clo.isTag && scope.row[clo.key]" size="medium">{{scope.row[clo.key]}}</el-tag>
            </template>
            <template v-else>
              <!-- 格式化列 -->
              <div v-if="clo.format" v-html="clo.format.method(scope.row[clo.key], scope.row, clo.format.params)"></div>
              <!-- 普通列 -->
              <span v-else>{{formatData(scope.row, clo.key)}}</span>
            </template>
          </template>
        </el-table-column>
      </template>
      <el-table-column v-if="handleWidth" :min-width="handleWidth" :label="$t('table.Handle')" fixed="right">
        <template slot-scope="scope">
          <!-- 插槽参数: row(当前行对象) index(当前行下标) -->
          <slot :row="scope.row" :index="scope.$index"></slot>
        </template>
      </el-table-column>
      <el-table-column v-else></el-table-column>
    </el-table>

    <!--预览图片-->
    <PreviewImage :win="previewImageWin" />
  </div>
</template>
<script>
import TableSetting from './table-setting'
import PreviewImage from '@/components/dialog/preview-image'
import { dateFormat, moneyFormat } from '@/filters/index'

export default {
  components: {
    TableSetting,
    PreviewImage
  },
  props: {
    // 操作栏最小宽度
    handleWidth: {
      type: Number,
      default: 0
    },
    // 页面类型 no-search:没有搜索栏 no-button：没有按钮 no-all：没有搜索栏和按钮
    pageType: {
      type: String,
      default: ''
    },
    // 列表数据
    data: {
      required: true,
      type: Array
    },
    // 表格行标识
    rowKey: {
      type: String,
      default: 'id'
    },
    // (唯一值) 表格列标识（值为''时表格不可手动配置） 用于TableSetting 组件中localStorage存储数据
    columnMark: {
      type: String,
      default: ''
    },
    // 表格列 数组中对象格式见（>数据格式说明1）
    columns: {
      required: true,
      type: Array
    }
  },
  data() {
    return {
      dateFormat, // 格式化时间
      moneyFormat, // 格式化金额
      columnList: [], // 表格列
      // 表格配置
      tableSet: {
        show: false // 是否显示表格配置窗口
      },
      isSelect: false, // 是否有选择功能
      selectData: [], // 被选中的列表
      // 预览图片弹框
      previewImageWin: {
        show: false,
        url: ''
      }
    }
  },
  created() {
    this.redraw()
    // 判断是否传入选择触发的事件来开启选择功能
    if (this.$listeners.select) {
      this.isSelect = true
    } else {
      this.isSelect = false
    }
  },
  methods: {
    /**
     * 普通数据格式化 支持对象嵌套
     * @param {Object} row
     * @param {Object} key
     */
    formatData(row, key) {
      if (key.includes('.')) {
        const keys = key.split('.')
        let data = row
        for (const item of keys) {
          data = data[item]
        }
        return data
      } else {
        return row[key]
      }
    },
    /**
     * 重绘表格
     */
    redraw() {
      // 从本地存储中获取表格列配置，如无则获取默认表格列
      if (this.columnMark) {
        let columnListTemp = JSON.parse(localStorage.getItem(this.columnMark))
        if (columnListTemp) {
          for (const item of this.columns) {
            item.fit = false // key title 字段是否一致 设置默认值
            for (const itemTemp of columnListTemp) {
              // 处理数据格式化的引用指向
              if (itemTemp.key === item.key) {
                itemTemp.format = item.format
                itemTemp.isSwitch = item.isSwitch
              }
              // 判断表格列字段 key title 是否改变过
              if (itemTemp.key === item.key && itemTemp.title === item.title) {
                item.fit = true
              }
            }
            // 字段 key title 如果有差异 清楚本地存储中的缓存数据
            if (!item.fit) {
              columnListTemp = null
              localStorage.removeItem(this.columnMark)
              break
            }
          }
        }
        this.columnList = columnListTemp || this.columns
      } else {
        this.columnList = this.columns
      }
    },
    /**
     * 表格-单击整行
     * @param {Object} row
     * @param {Object} column
     * @param {Object} event
     */
    rowClick(row, column, event) {
      if (this.isSelect) {
        this.$refs.customerTable.toggleRowSelection(row)
      }
    },
    /**
     * 表格-双击整行
     * @param {Object} row
     * @param {Object} column
     * @param {Object} event
     */
    rowDblclick(row, column, event) {
      if (this.isSelect) {
        // 功能待完善
      }
    },
    /**
     * 表格 多选框触发
     * @param {Array} selection
     */
    selectionChange(selection) {
      if (this.isSelect) {
        this.$emit('select', selection)
        this.selectData = selection
      }
    },
    /**
     * 表格高亮
     */
    rowClassName({ row, rowIndex }) {
      for (const item of this.selectData) {
        if (row[this.rowKey] === item[this.rowKey]) {
          return 'selected-row'
        }
      }
      return ''
    },
    /**
     * 图片预览
     * @param {String} url
     */
    preview(url) {
      this.previewImageWin.show = true
      this.previewImageWin.url = url
    }
  }
}
</script>
<style lang="less" scoped>
.table-content /deep/{
  position: relative;
  height: calc(100vh - var(--size-head-height) - 80px - 56px - 67px);
  margin: 0 20px;
  padding-top: 20px;
  &.no-search{
    height: calc(100vh - var(--size-head-height) - 56px - 67px);
  }
  &.no-button{
    height: calc(100vh - var(--size-head-height) - 80px - 67px);
  }
  &.no-all {
    height: calc(100vh - var(--size-head-height) - 67px);
  }
  th,
  td {
    height: 44px;
  }
  th {
    color: #666;
    background-color: #f6f4f4 !important;
  }
  .el-table__fixed-right-patch{
    background-color: transparent;
  }
  .el-table-column--selection .cell{
    padding-right: 10px;
  }
  .el-icon-s-tools{
    position: relative;
    top: 2px;
    font-size: 20px;
  }
  .el-icon-s-tools:hover{
    opacity: .8;
  }
  .table-img {
    height: 20px;
  }
  // 表格选中颜色
  /deep/.selected-row {
    background-color: #f2f7fd;
  }
}
</style>
